home *** CD-ROM | disk | FTP | other *** search
/ NeXT Enterprise Objects Framework 1.1 / NeXT Enterprise Objects Framework 1.1.iso / NextDeveloper / Examples / EnterpriseObjects / EOController / PeopleDemo_sybase / MainController.m < prev    next >
Encoding:
Text File  |  1994-09-14  |  7.6 KB  |  308 lines

  1. /* MainController.m
  2.  * You may freely copy, distribute, and reuse the code in this example.
  3.  * NeXT disclaims any warranty of any kind, expressed or  implied, as to its
  4.  * fitness for any particular use.
  5.  *
  6.  * Written by Mai Nguyen, NeXT Developer Support
  7.  *
  8.  */
  9.  
  10. #import "MainController.h"
  11. #import "Department.h"
  12. #import "strings.h"
  13.  
  14. @implementation MainController
  15.  
  16. - init
  17. {
  18.     [super init];
  19.     return self;
  20. }
  21.  
  22. - appDidInit:sender
  23. {
  24.     
  25.     dbDataSource = [masterController dataSource];
  26.     dbChannel = [dbDataSource databaseChannel];
  27.     adaptorChannel = [dbChannel adaptorChannel];
  28.     eoAdaptor = [[adaptorChannel adaptorContext] adaptor];
  29.     
  30.     
  31.     // Bring up a login panel and get the valid connection dictionary
  32.     
  33.      if(![eoAdaptor runLoginPanelAndValidateConnectionDictionary]) 
  34.         [NXApp terminate:self];
  35.     [eoAdaptor setConnectionDictionary: [eoAdaptor connectionDictionary]];
  36.  
  37.     rootEntity = [dbDataSource entity];
  38.     
  39.     [self setDelegates];
  40.     
  41.     // set up the controller to not alter the selection after a fetch  
  42.     [masterController setSelectsFirstObjectAfterFetch:NO];
  43.  
  44.     [self fetch:sender];    
  45.     return self;
  46. }
  47.  
  48. // Perform a fetch based on the latest options specified by user.  
  49.  
  50. - fetch:sender
  51. {
  52.     if (optionsPanel)
  53.         [optionsPanel orderOut:sender];
  54.         
  55.     [self setUpFetch:sender];
  56.  
  57.     [masterController fetch];
  58.     return self;
  59. }
  60.  
  61. - newRecord:sender
  62. {
  63.     int i;
  64.     
  65.     // Clear all the current values in the form cells to prepare
  66.     // for the insertion of a new record.
  67.      
  68.      for (i = 0; i < 5; i++)
  69.         [formMatrix setStringValue:"" at:i];
  70.     return self;
  71. }
  72.  
  73. - insert:sender
  74. {
  75.     // Disable the INSERT Button if the input is not valid  
  76.     if ([self validateRecord] == NO) {
  77.         [insertButton setState:0];
  78.         NXRunAlertPanel(NULL, ERR_INSERT_FAIL, NULL, NULL, NULL);
  79.     }
  80.     else {
  81.         [insertButton setState:1];
  82.         [masterController insert:sender];
  83.     }
  84.     return self;
  85. }
  86.  
  87.  
  88. // Set up the fetch order and specify a qualifier 
  89. // for the master table "Department" 
  90.  
  91. - setUpFetch:sender
  92.     const char    *inputString;
  93.     const char    *attrName = NULL;
  94.     EOQualifier *aQualifier;
  95.     id             fetchOrder;
  96.     id             sortAttribute;
  97.     int             orderType;
  98.  
  99.     // build the qualifier.
  100.     // If the input string is empty, fetch all records.
  101.      
  102.     inputString = [(TextField *)textField stringValue];
  103.      
  104.     if (inputString == NULL)
  105.         [dbDataSource setQualifier: [rootEntity qualifier]];
  106.     else {
  107.          aQualifier = [[[EOQualifier alloc] initWithEntity:rootEntity
  108.                         qualifierFormat:@"%A >= %d", @"DeptId", 
  109.                         [textField intValue]] autorelease];
  110.         [dbDataSource setQualifier:aQualifier];
  111.          }
  112.                                                      
  113.     // build the fetch order based on the first column of the master
  114.     // tableview
  115.       
  116.     orderType = [sortMatrix selectedTag];
  117.     attrName  = [[masterTableview columnAt:0] title];
  118.     sortAttribute = [rootEntity attributeNamed:[ [[NSString alloc]
  119.                                 initWithCString:attrName] autorelease]];
  120.     fetchOrder = [NSArray arrayWithObject:[[[EOAttributeOrdering alloc]
  121.          initWithAttribute:sortAttribute ordering: orderType] autorelease]];
  122.              
  123.     [dbDataSource setFetchOrder:fetchOrder];
  124.        return self;
  125. }
  126.  
  127.  
  128. - (BOOL) validateRecord
  129. {
  130.     int newId, newLocation;
  131.     BOOL result = YES;
  132.     
  133.     newId = [formMatrix intValueAt:0];
  134.     newLocation = [formMatrix intValueAt:2];
  135.     
  136.     // Do validation here  
  137.     if ( newId < 100 || newId > 999) {
  138.         NXRunAlertPanel(NULL, ERR_INVALID_ID, NULL, NULL, NULL);
  139.         result = NO;
  140.     }
  141.     if ( newLocation != 1101 && newLocation != 1103
  142.             && newLocation != 1104 && newLocation != 1106
  143.             && newLocation != 1207) {
  144.         NXRunAlertPanel(NULL, ERR_INVALID_LOCATION, NULL, NULL, NULL);
  145.         result = NO;
  146.     } 
  147.     return result;
  148.      
  149. }
  150. - setDelegates
  151. {
  152. #ifdef DEBUG     
  153.     [adaptorChannel setDebugEnabled:YES];
  154. #endif 
  155.     [adaptorChannel setDelegate:self];
  156.     [(EOController *) masterController setDelegate:self];
  157.     
  158.     return self;
  159. }
  160.  
  161. @end
  162.  
  163. @implementation MainController (EOAdaptorDelegation)
  164.  
  165. //This method is useful to trace SQL queries  
  166. - (void)adaptorChannel:channel
  167.     didEvaluateExpression:(NSString *)expression
  168. {
  169.     if (sqlPanel) {
  170.         [text appendToText:"SQL Query:\n"];
  171.         [text appendToText:[expression cString]];
  172.         [text appendToText:"\n"];
  173.     }
  174. }
  175. @end
  176.  
  177.  
  178. @implementation MainController (EOControllerDelegation)
  179.  
  180. // This method is called before each update. Since the controller has
  181. // buffer edits turned ON, this method is called when the user explicitly
  182. // presses the UPDATE button. 
  183.  
  184. - (NSDictionary *)controller:(EOController *)controller 
  185.     willSaveEdits: (NSDictionary *)edits 
  186.     toObject:object
  187. {
  188.     if ([self validateRecord] == YES)
  189.             return edits;
  190.     else {
  191.         NXRunAlertPanel(NULL, ERR_UPDATE_FAIL, NULL, NULL, NULL);
  192.         return nil;
  193.     }
  194. }
  195.  
  196. // Take the input from the formcells and create a new record.
  197. // This delegate method can be used to set up the default values of a newly
  198. // created EO. By default, we use the current user input in the formcells
  199. // to create a new record.
  200.  
  201.  
  202. - (BOOL)controller:(EOController *)controller willInsertObject:object atIndex: (unsigned)newIndex
  203. {
  204.     [object setDeptId: (int)[formMatrix intValueAt:0]];
  205.     [object setDepartmentName:[[[NSString alloc] initWithCString: 
  206.                     [formMatrix stringValueAt:1]] autorelease]];
  207.     [object setLocationId:(int)[formMatrix intValueAt:2]];
  208.          // The to-many relationship points to an empty autoreleased array    
  209.     [object setToEmployee:[NSArray array]];
  210.     return YES;
  211.     
  212. }
  213.  
  214. // After insertion, refetch object so that the derived attributes are 
  215. // properly redisplayed.
  216.  
  217. - (void)controller:(EOController *)controller didInsertObject:object
  218.     inDataSource:dataSource
  219. {
  220.     [dbChannel refetchObject:object];
  221. }
  222.  
  223. // After an update, refetch object so that the derived attributes are 
  224. // properly redisplayed.
  225.  
  226. - (void)controller:(EOController *)controller didUpdateObject:object
  227.     inDataSource:dataSource
  228. {
  229.     [dbChannel refetchObject:object];
  230. }    
  231.  
  232. // When the insert operation failed, remove the wrong record and rollback
  233. // the data source. A failure usually happens when trying to insert a duplicate
  234. // key. Since an insert operation adds a new record after the current
  235. // selection, the index has to be computed accordingly.
  236.  
  237.  
  238. - (EODataSourceFailureResponse)controller:(EOController *)controller
  239.     failedToInsertObject:object
  240.     inDataSource:dataSource;
  241. {
  242.     NXRunAlertPanel(NULL, ERR_INSERT_FAIL, NULL, NULL, NULL);
  243.      
  244.     [controller deleteObjectAtIndex:([masterTableview selectedRow] + 1)];
  245.     
  246.     return EORollbackDataSourceFailureResponse;
  247. }
  248.  
  249. - (EODataSourceFailureResponse) controller:(EOController *)controller
  250.     failedToUpdateObject:object
  251.     inDataSource:dataSource
  252. {
  253.     NXRunAlertPanel(NULL, ERR_UPDATE_FAIL, NULL, NULL, NULL);
  254.         // Restore object to its previous state
  255.     [dbChannel refetchObject:object];
  256.     
  257.     return EORollbackDataSourceFailureResponse;
  258. }
  259.  
  260.     
  261. // When deleting a department, we need to null all the references 
  262. // to that department. Therefore, the "toEmployee" relationship is
  263. // used to find the employee records attached to a given department.
  264. // All department ids will then be nulled out.
  265.   
  266.  
  267. - (BOOL)controller:controller willDeleteObject:object
  268. {
  269.     
  270.     NSArray *employeeArray = [object toEmployee];
  271.     NSEnumerator *enumerator = [employeeArray objectEnumerator];
  272.     EOGenericRecord    *employee;
  273.     
  274.     while((employee = [enumerator nextObject]) != nil) {
  275.         [employee setObject:[EONull null] forKey:@"DeptId"];
  276.         [(id)[controller dataSource] updateObject:employee];
  277.     }
  278.  
  279.     return YES;
  280. }
  281.  
  282.  
  283. // Implementing this delegate method allows the controller to discard
  284. // pending edits. In this example, pending edits are edits rejected by
  285. // the validation mechanism, hence they can be discarded.
  286.  
  287. - (BOOL) controllerWillDiscardEdits:(EOController *)controller
  288. {
  289.     return YES;
  290. }
  291.     
  292. @end
  293.  
  294. @implementation Text(printResults)
  295.  
  296. - appendToText:(const char *)newText
  297. {
  298.     int currentLength = [self textLength];
  299.  
  300.     [self setSel:currentLength :currentLength];
  301.     [self replaceSel:newText];
  302.     [self scrollSelToVisible];
  303.     return self;
  304. }
  305.  
  306. @end
  307.